package io.potato.core.util;

import org.springframework.util.Base64Utils;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.UUID;


/**
 * 字符串工具类
 * 
 * @author longshangbo@163.com
 *
 * <p>2017年6月22日 上午11:52:57</p>
 */
public abstract class StringUtils {
	
	/**
	 * 大写数字单位
	 */
	private static final String UNIT = "万千佰拾亿千佰拾万千佰拾元角分";
	
	/**
	 * 大写数字
	 */
	private static final String DIGIT = "零壹贰叁肆伍陆柒捌玖";
	
	/**
	 * 默认编码
	 */
	public static final String DEFAULT_CHARSET = "UTF-8";
	
	/**
	 * 逗号分隔符
	 */
	public static final String SEPARATOR_COMMA = ",";

	/**
	 * 下划线分隔符
	 */
	public static final String SEPARATOR_UNDERLINE = "_";
	
	/**
	 * 手机号码正则表达式（不能为空串）
	 */
	public static final String MOBILE_PATTERN = "^1[0-9]{10}$";
	
	/**
	 * 判断字符串是否为空字符串
	 * 
	 * 注意：如果字符串全由空格组成，那么视为空，返回true
	 * @param str 需要检测的目标字符串
	 */
	public static boolean isBlank(String str){
		return str == null || str.trim().isEmpty();
	}

	public static boolean isNotBlank(String str) {
	    return !isBlank(str);
    }
	
	/**
	 * 判断某个对象是否为空字符串，传入的对象的原始类型一定要是字符串
	 * 
	 * 注意：如果字符串全由空格组成，那么视为空，返回true
	 * @param obj 原始类型为字符串的对象
	 */
	public static boolean isObjectBlank(Object obj){
		return obj == null || obj.toString().trim().isEmpty();
	}
	
	/**
	 * 根据提供的分隔符拼接字符串数组
	 * 
	 * @param strs 字符串数组
	 * @param separator 分隔符
	 * @return 分隔的字符串
	 */
	public static String join(String[] strs, String separator){
		return join(Arrays.asList(strs), separator);
	}
	
	/**
	 * 根据提供的分隔符拼接字符串集合
	 * 
	 * @param strs 字符串集合
	 * @param separator 分隔符
	 * @return 分隔的字符串 
	 */
	public static String join(Collection<String> strs, String separator){
		if(CollectionUtils.isNullOrEmpty(strs)){
			return "";
		}
		
		if(separator == null){
			separator = SEPARATOR_UNDERLINE;
		}
		
		StringBuilder strSb = new StringBuilder();
		
		for(String str : strs){
			if(!isBlank(str)){
				strSb.append(str).append(separator);
			}
		}
		
		if(strSb.length() > 0){
			strSb.delete(strSb.length() - 1, strSb.length());
		}
		
		return strSb.toString();
	}
	
	/**
	 * 根据提供的分隔符拼接整型集合
	 * 
	 * @param ids 整型集合
	 * @param separator 分隔符
	 * @return 分隔的字符串
	 */
	public static String join(List<Integer> ids, String separator){
		if(CollectionUtils.isNullOrEmpty(ids)){
			return "";
		}
		
		if(separator == null){
			separator = SEPARATOR_UNDERLINE;
		}
		
		StringBuilder strSb = new StringBuilder();
		
		for(Integer id : ids){
			if(id != null){
				strSb.append(id).append(separator);
			}
		}
		
		return strSb.delete(strSb.length() - 1, strSb.length()).toString();
	}
	
	/**
	 * 根据提供的分隔符拼接整型数组
	 * 
	 * @param ids 整型数组
	 * @param separator 分隔符
	 * @return 分隔的字符串
	 */
	public static String join(Integer[] ids, String separator){
		return join(Arrays.asList(ids), separator);
	}
	
	/**
	 * 获取随机UUID字符串
	 * 
	 * @return 随机UUID字符串，无-号
	 */
	public static String getRandomUUID(){
		return UUID.randomUUID().toString().replaceAll("-", "");
	}
	
	/**
	 * 使用base64算法加密字符串
	 * 
	 * @param str 需要加密的字符串
	 * @return 加密之后的字符串
	 */
	public static String encryptWithBase64(String str){
		try {
			return Base64Utils.encodeToString(str.getBytes(DEFAULT_CHARSET));
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 使用base64解密
	 * 
	 * @param str 需要解密的字符串
	 * @return 解密之后的字符串
	 */
	public static String decrypWithBase64(String str){
		try {
			return new String(Base64Utils.decodeFromString(str), DEFAULT_CHARSET);
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 编码URI
	 * 
	 * @param uri 资源URI
	 * @return UTF-8编码之后的URI
	 */
	public static String encodeURI(String uri){
		try {
			return URLEncoder.encode(uri, DEFAULT_CHARSET);
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 解码URI
	 * 
	 * @param uri 资源URI
	 * @return UTF-8解码之后的URI
	 */
	public static String decodeURI(String uri){
		try {
			return URLDecoder.decode(uri, DEFAULT_CHARSET);
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 按照指定的分隔符分割字符串，并转化成Integer数组，适用于将
	 * 逗号分隔的数组转化成Integer数组
	 * 
	 * @param str 字符串
	 * @param separator 分隔符
	 * @return 目标数组
	 */
	public static Integer[] split(String str, String separator) {
		AssertUtils.isNotBlank(separator);
		
		if(isBlank(str)){
			return new Integer[0];
		}
		
		String[] strArr = str.split(separator);
		
		if(CollectionUtils.isNullOrEmpty(strArr)){
			return new Integer[0];
		}
		
		Integer[] intArr = new Integer[strArr.length];
		
		for(int i = 0, len = strArr.length; i < len; i++){
			intArr[i] = Integer.parseInt(strArr[i]);
		}
		
		return intArr;
	}
	
	/**
	 * 数字转大写
	 * 
	 * @param num 数字
	 * @return 大写描述
	 */
	public static String convertDigital(double num){
		long temp = Math.round(num * 100);
		
		if (temp == 0) {
			return "零元整";
		}
		
		String strValue = String.valueOf(temp);
		StringBuilder result = new StringBuilder();
		boolean isZero = false;
		
		for (int i = 0, len = strValue.length(), j = UNIT.length() - strValue.length(); i < len; i++, j++) {
			char ch = strValue.charAt(i);
			
			if (ch == '0') {
				isZero = true;
				
				if (UNIT.charAt(j) == '亿' 
						|| UNIT.charAt(j) == '万' || UNIT.charAt(j) == '元') {
					result.append(UNIT.charAt(j));
					isZero = false;
				}
			} else {
				if (isZero) {
					result.append("零");
					isZero = false;
				}
				
				result.append(DIGIT.charAt(ch - '0'));
				result.append(UNIT.charAt(j));
			}
		}
		
		String resultStr = result.toString();
		
		if (!resultStr.endsWith("分")) {
			resultStr += "整";
		}
		
		return resultStr.replaceAll("亿万", "亿");
	}

	/**
	 * 判断字符串是否为数字组成
	 * 
	 * @param str 字符串
	 * @return 是否是数字
	 */
	public static boolean isNumeric(String str) {
		if (!isBlank(str)) {
			return str.matches("^\\d+$");
		} 
		
		return false;
	}
	
	/**
	 * 判断字符串是否是小数
	 * 
	 * @param str 字符串
	 * @return 是否是小数
	 */
	public static boolean isDecimal(String str){
		if(!isBlank(str)){
			return str.matches("^[0-9]+([.]{1}[0-9]+)?$");
		}
		
		return false;
	}

    /**
     * 判断字符串是否yyyy-MM-dd日期格式
     * @param str 字符串
     * @return  是否合法的日期格式
     */
	public static boolean isDateFormat(String str) {
        if(!isBlank(str)){
            return str.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$");
        }

        return false;
    }

}
